<template>
  <!-- 分配权限 -->
  <el-dialog :title="title" :visible.sync="dialogVisible" width="400px">
    <div>
      <el-tree
        v-if="dialogVisible"
        ref="tree"
        v-loading="dialogPending"
        :props="defaultProps"
        :data="treeData"
        node-key="id"
        highlight-current
        show-checkbox
      >
      </el-tree>
    </div>
    <span slot="footer">
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="save">保存</el-button>
    </span>
  </el-dialog>
</template>

<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import { getByRolePermission, updateRolePermission } from "@/api/role";
import { getMenuTree } from "@/api/user";

@Component
export default class RolePermission extends Vue {
  public title = "权限分配";
  public dialogVisible = false;
  public dialogPending = false;
  defaultProps = {
    children: "children",
    label: "name",
  };

  treeData = [];
  public roleId!: number;

  async open(roleId: number) {
    this.roleId = roleId;
    this.dialogVisible = true;
    this.dialogPending = true;
    await this.fetchMenuTree();
    await this.fetchRolePermission();
    this.dialogPending = false;
  }

  async fetchMenuTree() {
    console.log("fetchMenuTree");
    const resp = await getMenuTree();
    this.treeData = resp.data;
  }

  async fetchRolePermission() {
    console.log("fetchTableData");
    const resp = await getByRolePermission(this.roleId);
    resp.data.forEach((id: number) => {
      // 没有子节点的节点才能勾选。 子节点选了，父节点会自动勾选
      const treeItem =
        this.treeDataFlatten.find((item: any) => item.id === id) || null;
      if (treeItem && treeItem.children.length === 0) {
        (this.$refs.tree as any).setChecked(id, true);
      }
    });
  }

  async save() {
    this.dialogPending = true;
    const ids = (this.$refs.tree as any)
      .getCheckedNodes(false, true)
      .map((item: any) => item.id);
    await updateRolePermission(this.roleId, ids);
    this.$message.success("更新成功");
    this.dialogVisible = false;
    this.dialogPending = false;
  }

  get treeDataFlatten() {
    const res: any = [];
    const flat = (arr: any) => {
      arr.forEach((item: any) => {
        res.push(item);
        flat(item.children || []);
      });
    };
    flat(this.treeData);
    return res;
  }
}
</script>

<style lang="scss" scoped></style>
